/**
 * @description 常用的lib工具函数方法封装
 * @author Tim
 * @since 2020/04/01
 * 
 */
import PType from "./PType.class";
import Modal from "./Modal.class";

export default class Utils {
    /**
     * @description 解析url中的二维码参数
     * @param {String} url 二位对应的地址参数
     * @param {String} pname 需要解析的参数名字
     */
    static parseUrlParams(url, pname) {
        if (typeof url === "undefined" || !url) {
            return null;
        }
        url = decodeURIComponent(url); //解码
        let reg = new RegExp(pname + "=([^&#@]*)(&|$|#|@)"); // 正则表达式匹配
        var r = url.match(reg);
        if (r != null) {
            return r[1];
        } else {
            return null;
        }
    }

    /**
     * @description 深度合并: 合并相同key并完全复制key
     * @param to
     * @param origins {多个参数}
     * @return {*}
     *
     * e.g.
     */
    static mergeDeep(to, ...origins) {
        origins.forEach(from => {
            if (!PType.isObject(from)) {
                return;
            }
            for (const key in from) {
                const value = from[key];
                if (PType.isObject(value)) {
                    if (to[key] === undefined) {
                        to[key] = {};
                    }
                    Utils.mergeDeep(to[key], value);
                } else {
                    to[key] = value;
                }
            }
        });

        return to;
    }

        /**
     * @description 深度合并: 合并相同两个类
     * @param to
     * @param origins {多个参数}
     * @return {*}
     *
     * e.g.
     */
    static mergeClass(to, ...origins) {
        origins.forEach(from => {
            for (const key in from) {
                const value = from[key];
                to[key] = value;
            }
        });

        return to;
    }

    /**
     * @description 过滤没有值的request参数
     * 受content-type:"application/x-www-form-urlencoded"类型影响
     * null undefined 会被序列号为String类型的字符串
     *
     * @param {*} params
     */
    static filterQueryParams(params = {}) {
        params = params;
        let result = {};
        Object.keys(params).forEach((v, i, arr) => {
            if (v && params[v] !== undefined && params[v] !== null) {
                result[v] = params[v];
            }
        });

        return result;
    }

    /**
     * @description 浮点数相乘
     * @param  {...any} args
     *
     * e.g numMul(4.5, 4.6, 6)...
     */
    static numMul(...args) {
        if (!args || !args.length) return 0;
        let num = 1; //运算结果
        let m = 0; //幂指数
        args.map(v => {
            v = v.toString(); //转换字符串
            let vdot = v.split(".")[1];
            vdot && (m += vdot.length); //获取小数位数
            num *= Number(v.replace(".", ""));
        });

        return num / Math.pow(10, m);
    }

    /**
     * @description 多个浮点型小数相加/减（传负数即可）
     * @param  {...any} args
     *
     * e.g numCount('1.2', 2)、numCount('1.2', '-0.5');
     */
    static numCount(...args) {
        if (!args || !args.length) return 0;
        if (args.length === 1) return Number(args);
        let num = 0; //运算结果
        let lArr = []; //小数点长度集合
        let m = 0; //10的幂指数值
        args.map(v => {
            v = v.toString(); //转换字符串
            let vdot = v.split(".")[1];
            lArr.push(vdot ? vdot.length : 0);
        });
        m = Math.pow(10, Math.max(...lArr));
        args.map(v => {
            v = Number(v);
            num += v * m;
        });

        return num / m;
    }

    /**
     * 去掉两边空格
     * @param {*} str string字符串值
     * @param {*} all bool 是否全部空格
     */
    static strTrim(str, all = false) {
        if (!str) return "";
        if (all) {
            return str.replace(/\s+/g, "");
        }

        return str.replace(/(^\s*)|(\s*$)/g, "");
    }

    /**
     * 防止暴力点击事件
     * @param {*} e 
     * @param {*} context 
     * @param {*} t 
     */
    static stopForceClick(e, context, t = 2000) {
        let timeStamp = e.timeStamp;
        return new Promise((resolve, reject) => {
            if (timeStamp - context.timeStamp < t) {
                Modal.toast("操作过于频繁, 请稍后再试~");
                return reject();
            }

            //已经点击
            context.timeStamp = timeStamp;

            resolve();
        });
    }

    /**
     * 手机号替换中间4位
     * @param {*} phone 
     */
    static phoneHide(phone) {
        if (!phone) return "";

        // 替换中间4位
        var reg = /^(\d{3})\d{4}(\d{4})$/;
        return phone.replace(reg, "$1****$2");
    }

    /**
     * 正则表达式:
     * 密码至少含有数字、字母、特殊字符任意2种组合
     * @param {*} str
     */
    static pwdValidate(str) {
        let hasNumReg = /\d+/; //至少含有1或多个数字
        let hasCharReg = /[a-zA-Z]+/; //至少含有1或者多个字母
        let charTmp = str.match(hasCharReg);
        let numTmp = str.match(hasNumReg);
        if (
            (charTmp && charTmp[0].length == str.length) ||
            (numTmp && numTmp[0].length == str.length) ||
            (!charTmp && !numTmp)
        ) {
            Modal.toast("输入的密码至少含有数字、字母、特殊字符任意2种组合");
            return false;
        }

        return true;
    }

}